//! 数据模型模块
//! 
//! 这个模块定义了应用程序中使用的所有数据模型，包括：
//! - 用户模型
//! - 认证相关模型
//! - API响应模型
//! - 请求模型

use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
use chrono::{DateTime, Utc};

/// 用户状态枚举
/// 
/// 定义用户账户的不同状态
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, sqlx::Type)]
#[sqlx(type_name = "user_status", rename_all = "lowercase")]
pub enum UserStatus {
    /// 活跃用户
    Active,
    /// 非活跃用户
    Inactive,
    /// 待激活用户
    Pending,
    /// 已禁用用户
    Disabled,
}

/// 用户角色枚举
/// 
/// 定义用户的不同角色和权限级别
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, sqlx::Type)]
#[sqlx(type_name = "user_role", rename_all = "lowercase")]
pub enum UserRole {
    /// 普通用户
    User,
    /// 管理员
    Admin,
    /// 超级管理员
    SuperAdmin,
}

/// 用户模型
/// 
/// 表示系统中的用户实体
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct User {
    /// 用户唯一标识符
    pub id: Uuid,
    /// 用户名（唯一）
    pub username: String,
    /// 邮箱地址（唯一）
    pub email: String,
    /// 密码哈希值（不序列化到JSON）
    #[serde(skip_serializing)]
    pub password_hash: String,
    /// 用户全名
    pub full_name: Option<String>,
    /// 用户头像URL
    pub avatar_url: Option<String>,
    /// 用户状态
    pub status: UserStatus,
    /// 用户角色
    pub role: UserRole,
    /// 账户创建时间
    pub created_at: DateTime<Utc>,
    /// 最后更新时间
    pub updated_at: DateTime<Utc>,
    /// 最后登录时间
    pub last_login_at: Option<DateTime<Utc>>,
}

/// 用户创建请求模型
/// 
/// 用于用户注册时的输入验证
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateUserRequest {
    /// 用户名
    pub username: String,
    /// 邮箱地址
    pub email: String,
    /// 密码
    pub password: String,
    /// 确认密码
    pub confirm_password: String,
    /// 用户全名
    pub full_name: Option<String>,
}

/// 用户更新请求模型
/// 
/// 用于更新用户信息时的输入验证
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateUserRequest {
    /// 用户名
    pub username: Option<String>,
    /// 邮箱地址
    pub email: Option<String>,
    /// 用户全名
    pub full_name: Option<String>,
    /// 用户头像URL
    pub avatar_url: Option<String>,
    /// 用户状态
    pub status: Option<UserStatus>,
    /// 用户角色
    pub role: Option<UserRole>,
}

impl Default for UpdateUserRequest {
    fn default() -> Self {
        Self {
            username: None,
            email: None,
            full_name: None,
            avatar_url: None,
            status: None,
            role: None,
        }
    }
}

/// 用户登录请求模型
/// 
/// 用于用户登录时的输入验证
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoginRequest {
    /// 邮箱地址或用户名
    pub email_or_username: String,
    /// 密码
    pub password: String,
}

/// 用户登录响应模型
/// 
/// 登录成功后返回的用户信息和访问令牌
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoginResponse {
    /// 访问令牌
    pub access_token: String,
    /// 刷新令牌
    pub refresh_token: String,
    /// 令牌类型（通常是"Bearer"）
    pub token_type: String,
    /// 令牌过期时间（秒）
    pub expires_in: u64,
    /// 用户信息
    pub user: UserInfo,
}

/// 用户信息模型
/// 
/// 用于API响应中返回的用户信息（不包含敏感信息）
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserInfo {
    /// 用户ID
    pub id: Uuid,
    /// 用户名
    pub username: String,
    /// 邮箱地址
    pub email: String,
    /// 用户全名
    pub full_name: Option<String>,
    /// 用户头像URL
    pub avatar_url: Option<String>,
    /// 用户状态
    pub status: UserStatus,
    /// 用户角色
    pub role: UserRole,
    /// 账户创建时间
    pub created_at: DateTime<Utc>,
    /// 最后更新时间
    pub updated_at: DateTime<Utc>,
    /// 最后登录时间
    pub last_login_at: Option<DateTime<Utc>>,
}

/// 用户查询参数模型
/// 
/// 用于用户列表查询时的过滤和分页参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserQuery {
    /// 页码
    pub page: Option<u32>,
    /// 每页数量
    pub limit: Option<u32>,
    /// 搜索关键词（用户名或邮箱）
    pub search: Option<String>,
    /// 用户状态过滤
    pub status: Option<UserStatus>,
    /// 用户角色过滤
    pub role: Option<UserRole>,
    /// 排序字段
    pub sort_by: Option<String>,
    /// 排序方向
    pub sort_order: Option<SortOrder>,
}

/// 排序方向枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum SortOrder {
    /// 升序
    Asc,
    /// 降序
    Desc,
}

/// API响应模型
/// 
/// 统一的API响应格式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiResponse<T> {
    /// 请求是否成功
    pub success: bool,
    /// 响应数据
    pub data: Option<T>,
    /// 错误信息
    pub error: Option<ApiError>,
    /// 响应元数据
    pub meta: Option<ResponseMeta>,
    /// 响应时间戳
    pub timestamp: DateTime<Utc>,
    /// 请求ID
    pub request_id: Option<String>,
}

/// API错误信息模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiError {
    /// 错误代码
    pub code: String,
    /// 错误消息
    pub message: String,
    /// 错误详情
    pub details: Option<serde_json::Value>,
    /// 字段错误（用于表单验证）
    pub field_errors: Option<std::collections::HashMap<String, Vec<String>>>,
}

/// 响应元数据模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResponseMeta {
    /// 分页信息
    pub pagination: Option<PaginationMeta>,
    /// 处理时间（毫秒）
    pub processing_time_ms: Option<u64>,
    /// 缓存命中标识
    pub cache_hit: Option<bool>,
    /// 其他元数据
    pub extra: Option<std::collections::HashMap<String, serde_json::Value>>,
}

/// 分页元数据模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginationMeta {
    /// 当前页码
    pub page: u32,
    /// 每页数量
    pub limit: u32,
    /// 总记录数
    pub total: u64,
    /// 总页数
    pub total_pages: u32,
    /// 是否有下一页
    pub has_next: bool,
    /// 是否有上一页
    pub has_prev: bool,
}

/// 分页响应模型
/// 
/// 用于分页查询的响应格式
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginatedResponse<T> {
    /// 数据列表
    pub data: Vec<T>,
    /// 分页信息
    pub pagination: PaginationMeta,
}

/// 健康检查响应模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthCheckResponse {
    /// 服务状态
    pub status: String,
    /// 服务版本
    pub version: String,
    /// 检查时间戳
    pub timestamp: DateTime<Utc>,
    /// 各项服务状态
    pub checks: std::collections::HashMap<String, ServiceCheck>,
}

/// 服务检查结果模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceCheck {
    /// 服务状态
    pub status: String,
    /// 响应时间（毫秒）
    pub response_time_ms: Option<u64>,
    /// 错误信息
    pub error: Option<String>,
    /// 额外信息
    pub details: Option<std::collections::HashMap<String, serde_json::Value>>,
}

/// JWT声明模型
/// 
/// 用于JWT令牌中的用户信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Claims {
    /// 用户ID
    pub sub: Uuid,
    /// 用户名
    pub username: String,
    /// 邮箱
    pub email: String,
    /// 用户角色
    pub role: UserRole,
    /// 令牌签发时间
    pub iat: i64,
    /// 令牌过期时间
    pub exp: i64,
    /// 令牌签发者
    pub iss: String,
    /// 令牌受众
    pub aud: String,
}

/// WebSocket消息类型枚举
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum WebSocketMessageType {
    /// 聊天消息
    Chat,
    /// 用户加入
    UserJoined,
    /// 用户离开
    UserLeft,
    /// 心跳包
    Ping,
    /// 心跳响应
    Pong,
    /// 系统消息
    System,
    /// 错误消息
    Error,
}

/// WebSocket消息模型
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WebSocketMessage {
    /// 消息类型
    pub message_type: WebSocketMessageType,
    /// 消息内容
    pub content: String,
    /// 发送者ID
    pub sender_id: Option<Uuid>,
    /// 房间ID
    pub room_id: Option<Uuid>,
    /// 消息时间戳
    pub timestamp: DateTime<Utc>,
}

// 从User到UserInfo的转换实现已移至auth.rs中

/// API响应构建器
impl<T> ApiResponse<T> {
    /// 创建成功响应
    pub fn success(data: T) -> Self {
        Self {
            success: true,
            data: Some(data),
            error: None,
            meta: None,
            timestamp: Utc::now(),
            request_id: None,
        }
    }

    /// 创建成功响应（带元数据）
    pub fn success_with_meta(data: T, meta: ResponseMeta) -> Self {
        Self {
            success: true,
            data: Some(data),
            error: None,
            meta: Some(meta),
            timestamp: Utc::now(),
            request_id: None,
        }
    }

    /// 创建错误响应
    pub fn error(code: &str, message: &str) -> Self {
        Self {
            success: false,
            data: None,
            error: Some(ApiError {
                code: code.to_string(),
                message: message.to_string(),
                details: None,
                field_errors: None,
            }),
            meta: None,
            timestamp: Utc::now(),
            request_id: None,
        }
    }

    /// 添加请求ID
    pub fn with_request_id(mut self, request_id: String) -> Self {
        self.request_id = Some(request_id);
        self
    }
}

/// 分页响应构建器
impl<T> PaginatedResponse<T> {
    /// 创建分页响应
    pub fn new(data: Vec<T>, page: u32, limit: u32, total: u64) -> Self {
        let total_pages = ((total as f64) / (limit as f64)).ceil() as u32;
        let has_next = page < total_pages;
        let has_prev = page > 1;

        Self {
            data,
            pagination: PaginationMeta {
                page,
                limit,
                total,
                total_pages,
                has_next,
                has_prev,
            },
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_user_info_from_user() {
        let user = User {
            id: Uuid::new_v4(),
            username: "test_user".to_string(),
            email: "test@example.com".to_string(),
            password_hash: "hashed_password".to_string(),
            full_name: Some("Test User".to_string()),
            avatar_url: None,
            status: UserStatus::Active,
            role: UserRole::User,
            created_at: Utc::now(),
            updated_at: Utc::now(),
            last_login_at: None,
        };

        let user_info: UserInfo = user.into();
        assert_eq!(user_info.username, "test_user");
        assert_eq!(user_info.email, "test@example.com");
    }

    #[test]
    fn test_api_response_success() {
        let response = ApiResponse::success("test data");
        assert!(response.success);
        assert!(response.data.is_some());
        assert!(response.error.is_none());
    }

    #[test]
    fn test_api_response_error() {
        let response = ApiResponse::<String>::error("TEST_ERROR", "Test error message");
        assert!(!response.success);
        assert!(response.data.is_none());
        assert!(response.error.is_some());
    }

    #[test]
    fn test_paginated_response() {
        let data = vec!["item1", "item2", "item3"];
        let response = PaginatedResponse::new(data.clone(), 1, 10, 3);
        
        assert_eq!(response.data.len(), 3);
        assert_eq!(response.pagination.page, 1);
        assert_eq!(response.pagination.limit, 10);
        assert_eq!(response.pagination.total, 3);
        assert_eq!(response.pagination.total_pages, 1);
        assert!(!response.pagination.has_next);
        assert!(!response.pagination.has_prev);
    }
}
